package services

import (
	"errors"
	"fmt"
	"hft/Database/admin"
	fileopera "hft/Database/admin/file/file_opera"
	"hft/Http/Models/dao"
	"hft/Http/Models/request"
	"hft/Http/Services/base"
	utils "hft/Http/Utils"
	"hft/e"
	"hft/global"
	"hft/tools"
	"regexp"

	"gorm.io/gorm"
)

type Broker struct{}

// 获取经纪人列表
func (*Broker) GetBrokerList(claims tools.BaseClaims, paginate *request.BrokerPage) (data *utils.Page, err error) {
	var brokers []*admin.Account
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return nil, errors.New(e.AccountNotExist)
	}
	global.OC_DB.Scopes(dao.BrokerDao.GetBrokerList(paginate, account.RegionLink, fmt.Sprintf("%v%v,", account.AccountLink, account.ID), global.OC_DB)).Find(&brokers).Offset(-1).Limit(-1).Count(&paginate.Total)
	paginate.Data = brokers
	return &paginate.Page, nil
}

func (*Broker) CreateBroker(data *admin.Account, claims tools.BaseClaims) (err error) {

	var role *admin.Role

	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	global.OC_DB.First(&role, 33)
	// res1, err1 := tools.ValidIDCard(data.IDCard, data.RealName)

	// if res1.Data.ResponseCode != "0" {
	// 	return errors.New(e.IDCardNotPass)
	// }

	// if err1 != nil {
	// 	return errors.New(e.ErrorInfo)
	// }

	data.RoleId = role.ID
	data.Link = fmt.Sprintf("%v%v,", role.Link, role.ID)
	data.AccountLink = fmt.Sprintf("%v%v,", account.AccountLink, account.ID)
	data.PID = account.ID
	data.RoleName = role.RoleName
	data.RegionLink = account.RegionLink

	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {

		res := tx.Where("username = ?", data.Username).FirstOrCreate(&data)

		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}

		if res.RowsAffected == 0 {
			return errors.New(e.AccountHasExit)
		}

		code := utils.GetDns(data.LouPan, data.Phone, tx)

		if code != "0" {
			return errors.New(e.PhoneAddFail)
		}

		// 创建目录
		fileopera.CreateDirSystem(data.Username)
		fileopera.CreateRoot(data.Username)

		return nil

	})

	return nil

}

func (*Broker) EditBroker(data *admin.Account, claims tools.BaseClaims) (err error) {
	var account *admin.Account

	var role *admin.Role

	res1, err1 := tools.ValidIDCard(data.IDCard, data.RealName)

	if res1.Data.ResponseCode != "0" {
		return errors.New("身份证验证不通过")
	}

	if err1 != nil {
		return errors.New("未知错误")
	}

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("无该账号信息")
	}

	err = global.OC_DB.Where("can_bind_lou_pan = ?", 1).First(&role).Error

	if err != nil {
		return errors.New("你还未创建该角色")
	}

	var broker *admin.Account

	err = global.OC_DB.First(&broker, data.ID).Error

	if err != nil {
		return errors.New("该经纪人信息不存在")
	}

	var password string

	if utils.DeleteStringSpace(data.Password) == "" {
		password = broker.Password
	} else {
		password = data.Password
	}

	global.OC_DB.Transaction(func(tx *gorm.DB) error {

		var broker *admin.Account

		err = tx.Model(&broker).Where("id = ?", data.ID).Updates(map[string]interface{}{
			"password":  password,
			"avatar":    data.Avatar,
			"id_card":   data.IDCard,
			"real_name": data.RealName,
		}).Error

		if err != nil {
			return errors.New("未知错误500")
		}

		tx.Preload("LouPan", func(db *gorm.DB) *gorm.DB {
			return db.Preload("SellLouPanInfo")
		}).First(&broker, data.ID)
		// 新去掉这些楼盘关于该经纪人的手机
		code := utils.DeletePhone(broker.LouPan, broker.Phone, account.Phone, tx)
		if code != "0" {
			return errors.New("更换楼盘无效")
		}
		code = utils.GetDns(data.LouPan, broker.Phone, tx)

		if code != "0" {
			return errors.New("添加楼盘无效")
		}
		tx.Model(&broker).Association("LouPan").Replace(data.LouPan)

		return nil
	})

	return nil

}

func (*Broker) ReplaceLouPan(accountId int, ids []int, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	var louPans []*admin.LouPan

	var broker *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("无该账号信息")
	}

	err = global.OC_DB.First(&broker, accountId).Error

	if err != nil {
		return errors.New("未知错误500")
	}

	match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.AccountLink), broker.AccountLink)

	if !match {
		return errors.New("你无权修改该经纪人配置")
	}

	err = global.OC_DB.Where("region_link REGEXP ?", account.RegionLink).Find(&louPans, ids).Error

	if err != nil {
		return errors.New("未知错误500")
	}

	global.OC_DB.Model(&broker).Association("LouPan").Replace(louPans)

	return nil
}

// 获取当前所有楼盘名称
func (*Broker) GetAllLouPan(request *request.SearchLou, claims tools.BaseClaims) (list []*admin.LouPan, err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return nil, errors.New("账号信息不存在")
	}

	var lous []*admin.LouPan

	name := utils.DeleteStringSpace(request.Name)

	global.OC_DB.Scopes(dao.BrokerDao.GetAllLouPan(name, account.RegionLink, global.OC_DB)).Preload("SellLouPanInfo").Find(&lous)

	return lous, nil
}

func (*Broker) Delete(ids []int, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("找不到该账号信息")
	}

	var accountList []*admin.Account

	global.OC_DB.Find(&accountList, ids)

	if !utils.IsBelongThisAccount(accountList, account) {
		return errors.New("你无权删除经纪人信息")
	}

	err = global.OC_DB.Model(&admin.Account{}).Unscoped().Delete(&accountList).Error

	if err != nil {
		return errors.New("未知错误500")
	}

	return nil

}

func (*Broker) Status(broker *admin.Account, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("找不到该账号信息")
	}

	err = global.OC_DB.First(&broker, broker.ID).Error

	if err != nil {
		return errors.New("找不到该经济人信息")
	}

	match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.RegionLink), broker.RegionLink)

	if !match {
		return errors.New("你无权修改该经纪人信息")
	}

	global.OC_DB.Model(&admin.Account{}).Where("id = ?", broker.ID).Update("status", broker.Status)

	return nil

}

func (*Broker) SendGold(ID int, Num int64, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("找不到该账号信息")
	}

	var broker *admin.Account

	err = global.OC_DB.Preload("AccountExpand").First(&broker, ID).Error

	if err != nil {
		return errors.New("该经纪人不存在")
	}

	match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.AccountLink), broker.AccountLink)

	if !match {
		return errors.New("你无权给改经纪人赠送金币")
	}

	var nowGold = broker.AccountExpand.Score + uint(Num)

	err = global.OC_DB.Model(&admin.AccountExpand{}).Where("account_id = ?", broker.ID).Update("score", nowGold).Error

	if err != nil {
		return errors.New("超出最大金币范围，请让经纪人尽快使用金币")
	}

	return nil
}

var BrokerService = new(Broker)
